package com.pvdnc.riru.appinjector;

import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class FileUtils {
    private static final String TAG=FileUtils.class.getSimpleName();

    public static abstract class BlockCallback{
        public abstract void onBlockReceived(byte[] blockData,int length) throws IOException;
    }

    public static void read(InputStream is,BlockCallback callback) throws IOException{
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = is.read(buffer, 0, 1024)) != -1) {
                callback.onBlockReceived(buffer,length);
            }
    }

    public static byte[] read(InputStream is)throws IOException {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            read(is, new BlockCallback() {
                @Override
                public void onBlockReceived(byte[] blockData, int length) throws IOException {
                    bos.write(blockData, 0, length);
                }
            });
            return bos.toByteArray();
        }
    }

    public static void read(File file,BlockCallback callback)throws IOException{
        try(FileInputStream fis=new FileInputStream(file)){
            read(fis,callback);
        }
    }

    public static byte[] read(File file)throws IOException{
        try(ByteArrayOutputStream bos=new ByteArrayOutputStream()){
            read(file, new BlockCallback() {
                @Override
                public void onBlockReceived(byte[] blockData, int length) throws IOException {
                    bos.write(blockData,0,length);
                }
            });
            return bos.toByteArray();
        }
    }

    public static String readString(File file) throws IOException{
        byte[] data=read(file);
        return new String(data);
    }

    public static String readString(InputStream is) throws IOException{
        byte[] data=read(is);
        return new String(data);
    }

    public static void copy(final File srcFile, File dstFile) throws IOException{
        long totalSize=srcFile.length();
        Log.d(TAG,"attempt to copy "+srcFile+"("+totalSize+")");
        try(FileOutputStream fos=new FileOutputStream(dstFile)) {
            read(srcFile, new BlockCallback() {
                @Override
                public void onBlockReceived(byte[] blockData, int length) throws IOException{
                    fos.write(blockData,0,length);
                }
            });
        }
        Log.d(TAG,"finish copying "+srcFile+" -> "+dstFile);
    }

    public static void write(File file,byte[] data,boolean append)throws IOException{
        try(FileOutputStream fos=new FileOutputStream(file,append)){
            fos.write(data);
        }
    }

    public static void write(File file,String str)throws IOException{
        byte[] data=str.getBytes();
        write(file,data,false);
    }

    public static void deleteOrThrow(File file) throws IOException {
        if(!file.delete())
            throw new IOException("fail to delete existed file:"+file);
    }
}
